import { createStore } from "solid-js/store";
import { Draggable } from "../src";

export default function App() {
    const [state, setState] = createStore({
        activeDrags: 0,
        deltaPosition: {
            x: 0, y: 0
        },
        controlledPosition: {
            x: -400, y: 200
        }
    })
    const onStart = () => {
        setState('activeDrags', state.activeDrags + 1);
    };

    const onStop = () => {
        setState('activeDrags', state.activeDrags - 1);
    };

    const onDrop = (e) => {
        setState('activeDrags', state.activeDrags - 1);
        if (e.target.classList.contains("drop-target")) {
            alert("Dropped!");
            e.target.classList.remove('hovered');
        }
    };

    const handleDrag = (e, ui) => {
        const { x, y } = state.deltaPosition;
        setState({
            deltaPosition: {
                x: x + ui.deltaX,
                y: y + ui.deltaY,
            }
        });
    };
    const onDropAreaMouseEnter = (e) => {
        if (state.activeDrags) {
            e.target.classList.add('hovered');
        }
    }
    const onDropAreaMouseLeave = (e) => {
        e.target.classList.remove('hovered');
    }

    const onControlledDrag = (e, position) => {
        const { x, y } = position;
        setState('controlledPosition', 'x', x);
        setState('controlledPosition', 'y', y);
    };

    const onControlledDragStop = (e, position) => {
        onControlledDrag(e, position);
        onStop();
    };

    const adjustXPos = (e) => {
        e.preventDefault();
        e.stopPropagation();
        const { x, y } = state.controlledPosition;
        setState('controlledPosition', 'x', x - 10);
    };

    const adjustYPos = (e) => {
        e.preventDefault();
        e.stopPropagation();
        const { controlledPosition } = state;
        const { x, y } = controlledPosition;
        setState('controlledPosition', 'y', y - 10 );
    };

    const dragHandlers = { onStart: onStart, onStop: onStop };
    return <div>
        <Draggable {...dragHandlers}>
            <div class="drag-box">I can be dragged anywhere</div>
        </Draggable>
        <Draggable axis="x" {...dragHandlers}>
            <div class="drag-box cursor-x">I can only be dragged horizonally (x axis)</div>
        </Draggable>
        <Draggable axis="y" {...dragHandlers}>
            <div class="drag-box cursor-y">I can only be dragged vertically (y axis)</div>
        </Draggable>
        <Draggable onStart={() => false}>
            <div class="drag-box">I don't want to be dragged</div>
        </Draggable>
        <Draggable onDrag={handleDrag} {...dragHandlers}>
            <div class="drag-box">
                <div>I track my deltas</div>
                <div>x: {state.deltaPosition.x.toFixed(0)}, y: {state.deltaPosition.y.toFixed(0)}</div>
            </div>
        </Draggable>
        <Draggable handle="strong" {...dragHandlers}>
            <div class="drag-box no-cursor">
                <strong class="cursor"><div>Drag here</div></strong>
                <div>You must click my handle to drag me</div>
            </div>
        </Draggable>
        <Draggable handle="strong">
            <div class="drag-box no-cursor" style={{ display: 'flex', 'flex-direction': 'column' }}>
                <strong class="cursor"><div>Drag here</div></strong>
                <div style={{ overflow: 'scroll' }}>
                    <div style={{ background: 'yellow', 'white-space': 'pre-wrap' }}>
                        I have long scrollable content with a handle
                        {'\n' + Array(40).fill('x').join('\n')}
                    </div>
                </div>
            </div>
        </Draggable>
        <Draggable cancel="strong" {...dragHandlers}>
            <div class="drag-box">
                <strong class="no-cursor">Can't drag here</strong>
                <div>Dragging here works</div>
            </div>
        </Draggable>
        <Draggable grid={[25, 25]} {...dragHandlers}>
            <div class="drag-box">I snap to a 25 x 25 grid</div>
        </Draggable>
        <Draggable grid={[50, 50]} {...dragHandlers}>
            <div class="drag-box">I snap to a 50 x 50 grid</div>
        </Draggable>
        <Draggable bounds={{ top: -100, left: -100, right: 100, bottom: 100 }} {...dragHandlers}>
            <div class="drag-box">I can only be moved 100px in any direction.</div>
        </Draggable>
        {/* <Draggable {...dragHandlers}>
            <div class="drag-box drop-target" onMouseEnter={onDropAreaMouseEnter} onMouseLeave={onDropAreaMouseLeave}>I can detect drops from the next box.</div>
        </Draggable>
        <Draggable {...dragHandlers} onStop={onDrop}>
            <div class={`drag-box ${state.activeDrags ? "no-pointer-events" : ""}`}>I can be dropped onto another box.</div>
        </Draggable> */}

        <div class="drag-box" style={{ height: '500px', width: '500px', position: 'relative', overflow: 'auto', padding: '0' }}>
            <div style={{ height: '1000px', width: '1000px', padding: '10px' }}>
                <Draggable bounds="parent" {...dragHandlers}>
                    <div class="drag-box">
                        I can only be moved within my offsetParent.<br /><br />
                        Both parent padding and child margin work properly.
                    </div>
                </Draggable>
                <Draggable bounds="parent" {...dragHandlers}>
                    <div class="drag-box">
                        I also can only be moved within my offsetParent.<br /><br />
                        Both parent padding and child margin work properly.
                    </div>
                </Draggable>
            </div>
        </div>

        <Draggable bounds="body" {...dragHandlers}>
            <div class="drag-box">
                I can only be moved within the confines of the body element.
            </div>
        </Draggable>

        <Draggable {...dragHandlers}>
            <div class="drag-box" style={{ position: 'absolute', bottom: '100px', right: '100px' }}>
                I already have an absolute position.
            </div>
        </Draggable>

        <Draggable defaultPosition={{ x: 25, y: 25 }} {...dragHandlers}>
            <div class="drag-box">
                {"I have a default position of {x: 25, y: 25}, so I'm slightly offset."}
            </div>
        </Draggable>

        <Draggable positionOffset={{ x: '-10%', y: '-10%' }} {...dragHandlers}>
            <div class="drag-box">
                {'I have a default position based on percents {x: \'-10%\', y: \'-10%\'}, so I\'m slightly offset.'}
            </div>
        </Draggable>

        <Draggable position={state.controlledPosition} {...dragHandlers} onDrag={onControlledDrag}>
            <div class="drag-box">
                My position can be changed programmatically. <br />
                I have a drag handler to sync state.
                <div>
                    <a href="#" onClick={adjustXPos}>Adjust x ({state.controlledPosition.x})</a>
                </div>
                <div>
                    <a href="#" onClick={adjustYPos}>Adjust y ({state.controlledPosition.y})</a>
                </div>
            </div>
        </Draggable>

        <Draggable position={state.controlledPosition} {...dragHandlers} onStop={onControlledDragStop}>
            <div class="drag-box">
                My position can be changed programmatically. <br />
                I have a dragStop handler to sync state.
                <div>
                    <a href="#" onClick={adjustXPos}>Adjust x ({state.controlledPosition.x})</a>
                </div>
                <div>
                    <a href="#" onClick={adjustYPos}>Adjust y ({state.controlledPosition.y})</a>
                </div>
            </div>
        </Draggable>
    </div>
}